package cn.cew.bytespyserver.jad;

import cn.cew.bytespyserver.comm.Constants;
import cn.cew.bytespyserver.tool.BaseUtils;
import lombok.extern.slf4j.Slf4j;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;

/**
 * @author chenenwei
 * @version 1.0.0
 * @description TODO
 * @createTime 2022-10-13 15:47:00
 */
@Slf4j
public class Jad {

    public static void decompile (String classFilePath, String ourDir, String outFileName) throws Exception {

        if (!classFilePath.endsWith(".class")) {
            classFilePath = classFilePath + ".class";
        }
        if (!outFileName.endsWith(".java")) {
            outFileName =  outFileName + ".java";
        }
        String os = System.getProperty("os.name");
        if (BaseUtils.isNotEmpty(os)) {
            String osName = os.toLowerCase();
            //Windows操作系统
            if (osName.startsWith("windows")) {
                exec("windows", new String[]{"cmd.exe", "/C"}, "jad.exe", ourDir, outFileName, classFilePath);
            } else if (osName.startsWith("linux")) {
                //Linux操作系统
                exec("linux", new String[]{"/bin/sh", "-c"}, "jad", ourDir, outFileName, classFilePath);
            } else if (osName.startsWith("mac")) {
                //mac操作系统
                exec("mac", new String[]{"open" , "-a"}, "jad", ourDir, outFileName, classFilePath);
            } else {
                log.error("暂时不支持当前系统java反编译");
                throw new Exception("暂时不支持当前系统java反编译");
            }
        }
    }

    /**
     * jad 反编译
     * @param osName 操作系统名称
     * @param binFile  jad 二进制文件名,如jad.exe、jad
     * @param outFileName 输出文件名，如 Test.java
     * @param classFilePath calss文件绝对路径，如：
     * @return
     */
    public static void exec (String osName, String[] cmdPrefix, String binFile, String outDir, String outFileName, String classFilePath) throws IOException, InterruptedException {

        // jar所在路径
        String projectPath = BaseUtils.getProjectPath();
        // jar可执行绝对路径
        String jadPath = projectPath + File.separator + "bin"+ File.separator + osName + File.separator + binFile;
        // 反编译输出路径
        if (BaseUtils.isEmpty(outDir)) {
            outDir = projectPath + File.separator + Constants.TEMP_JAVA_DIR + File.separator;
        }
        classFilePath = projectPath + File.separator + Constants.TEMP_CLASS_DIR + File.separator + classFilePath;
        String[] cmd = new String [] { cmdPrefix[0], cmdPrefix[1], jadPath, "-p", "-o", "-d", outDir, classFilePath,  ">", outFileName};
        log.debug("【执行反编译】 {}", String.join(" ", Arrays.asList(cmd)));
        Process process = Runtime.getRuntime().exec(cmd, null, new File(outDir));
        InputStreamReader inputStream = new InputStreamReader(process.getInputStream());
        BufferedReader input = new BufferedReader(inputStream);
        String line;
        while ((line = input.readLine()) != null){
            log.debug(line);
        }
    }
}
